package com.itlong.cloud.commons.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.itlong.cloud.POJO.DTO.app.AppElevatorAuthDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.app.AppCloudIntercomsVO;
import com.itlong.cloud.POJO.VO.app.AppElevatorAuthVO;
import com.itlong.cloud.POJO.VO.app.AppElevatorInfoVO;
import com.itlong.cloud.POJO.VO.app.AppEntranceOrCloudIntercomAuthVO;
import com.itlong.cloud.POJO.VO.common.CloudEntranceVO;
import com.itlong.cloud.POJO.VO.property.*;
import com.itlong.cloud.app.dao.IAppDeviceDao;
import com.itlong.cloud.commons.dao.*;
import com.itlong.cloud.commons.service.IPushCloudEntranceChangeLogService;
import com.itlong.cloud.commons.thread.queue.process.queue.SendIotPushMessageQueue;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.equip.app.IAppDeviceServiceClient;
import com.itlong.cloud.property.dao.ICloudIntercomDeviceServiceDao;
import com.itlong.cloud.property.dao.IDeviceEntranceInfoDao;
import com.itlong.cloud.property.dao.IPropertyEquipDao;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <desc>
 *      云门禁响应硬件结果业务处理服务层接口实现类
 * </desc>
 *
 * @createDate 2019/02/26
 */
@Service
public class PushCloudEntranceChangeLogServiceImpl implements IPushCloudEntranceChangeLogService {

    private static final Logger LOG = LoggerFactory.getLogger(PushCloudEntranceChangeLogServiceImpl.class);

    @Autowired
    private ICloudEntranceDao iCloudEntranceDao;

    @Autowired
    private IPushCloudEntranceChangeLogDao iPushCloudEntranceChangeLogDao;

    @Autowired
    private IPushCloudElevatorChangeLogDao iPushCloudElevatorChangeLogDao;

    @Autowired
    ICloudTalkPushCloudIntercomChangeLogDao iCloudTalkPushCloudIntercomChangeLogDao;

    @Autowired
    ICloudIntercomDeviceServiceDao iCloudIntercomDeviceServiceDao;

    @Autowired
    SendIotPushMessageQueue sendIotPushMessageQueue;

    @Autowired
    IAppDeviceDao iAppDeviceDao;

    @Autowired
    MessageSender messageSender;

    @Autowired
    RedisService redisService;


    private ExecutorService cachedThreadPool ;

    @Autowired
    IPropertyEquipDao iPropertyEquipDao;

    @Autowired
    ICloudElevatorDao iCloudElevatorDao;

    @PostConstruct
    public void init() {
        cachedThreadPool = Executors.newFixedThreadPool(100);
    }


    @Autowired
    IDeviceEntranceInfoDao iDeviceEntranceInfoDao;

    /**
     * <desc>
     *      任务调度执行同步业务指令至响应硬件结果表
     * </desc>
     *
     * @author wangzhi
     * @createDate 2019/02/26
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void timeTaskPushCloudEntrance() throws Exception {
        List<DeviceBusinessEntranceChangeLogPO> business = iCloudEntranceDao.getPendingBusiness(null,null);
        if (business != null && !business.isEmpty()) {
            //获取当前需要进行业务同步的所有项目
            Set<String> projectIds = new HashSet<>();
            for(DeviceBusinessEntranceChangeLogPO po : business){
                projectIds.add(po.getProjectId());
            }
//            projectIds.add("00000126");
            //遍历项目id，以项目为中心
            for (String projectId : projectIds) {
                //查找是否有全量更新
                if (business.stream().anyMatch(po -> CloudEntranceChangeBusinessEnum.PUSH_RE_LOGIN.getCommandType().equals(po.getCommandType()) && po.getProjectId().equals(projectId))) {
                    //云门禁业务服务器地址变更 /device/login
//                    this.updateFull(projectId);
                    continue;
                }
            }
        }
    }

    /**
     * <desc>
     *      全量更新
     * </desc>
     *
     * @param projectId 项目id
     * @author wangzhi
     * @createDate 2019/02/27
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void updateFull(String projectId,String params){
        try {
            List<PushCloudEntranceChangeLogPO> full =new ArrayList<>();
            // 获取所有云门禁设备
            List<DeviceEntranceInfoPO> clouds = iCloudEntranceDao.getCloudEntranceByProjectId(projectId);
            String iotFlag = StringHandlerUtil.getNullOrStringForObject(JsonUtil.toObject(params,HashMap.class).get("iotFlag"));
            for(DeviceEntranceInfoPO cloud : clouds) {
                PushCloudEntranceChangeLogPO push = new PushCloudEntranceChangeLogPO();
                push.setCommandId(LogicIdUtil.bussinessId());
                push.setDeviceUnique(cloud.getDeviceUnique());
                push.setSn(cloud.getSn());
                push.setCommandType(PushCloudEntranceChangeEnum.PUSH_FULL.getType());
                push.setCommandData("/device/login");
                if(StringUtils.isNotBlank(iotFlag)) {
                    push.setIotFlag(Integer.valueOf(iotFlag));
                }
                push.setCommandStatus(0);
                push.setStatus(DataStatusEnum.NORMAL.getType());
                push.setCreateTime(new Date());
                full.add(push);
            }
            if(!full.isEmpty()){
                iPushCloudEntranceChangeLogDao.batchSave(full);
                this.sendIotMessage(full);
            }
        }catch (Exception e){
            throw new DataAccessException("【定时任务】同步云门禁业务指令至响应硬件结果表全量更新执行失败，当前时间】:" +
                    DateUtil.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss") + "："+e);
        }
    }

    /**
     * <desc>
     *      云门禁单个设备物理地址变更
     * </desc>
     *
     * @param business 业务数据
     * @author wangzhi
     * @createDate 2019/02/27
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public synchronized void setPushDeviceOne(List<DeviceBusinessEntranceChangeLogPO> business){
        try {
            List<PushCloudEntranceChangeLogPO> devices = new ArrayList<>();
            Set<String> deviceSet=new HashSet<>();
            for(DeviceBusinessEntranceChangeLogPO bus : business){
                Map<String,Object> map=JsonUtil.toObject(bus.getCommandParameter(), HashMap.class);
                if(deviceSet.add(map.get("deviceUnique").toString())){
                    PushCloudEntranceChangeLogPO push=new PushCloudEntranceChangeLogPO();
                    push.setCommandId(LogicIdUtil.bussinessId());
                    push.setDeviceUnique(map.get("deviceUnique").toString());
                    push.setSn(map.get("sn") == null ? "" : map.get("sn").toString());
                    push.setCommandType(PushCloudEntranceChangeEnum.PUSH_FULL.getType());
                    push.setCommandData("/device/login");
                    push.setCommandStatus(0);
                    push.setStatus(DataStatusEnum.NORMAL.getType());
                    push.setCreateTime(new Date());
                    devices.add(push);
                }
            }
            if (!devices.isEmpty()) {
                iPushCloudEntranceChangeLogDao.batchSave(devices);
                this.sendIotMessage(devices);
            }
        }catch (Exception e){
            throw new DataAccessException("【定时任务】同步云门禁业务指令至响应硬件结果表单个设备物理地址变更执行失败，当前时间】:" +
                    DateUtil.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss") + "："+e);
        }
    }

    /**
     * <desc>
     *      处理推送硬件响应项目信息
     * </desc>
     *
     * @param business 业务数据
     * @author wangzhi
     * @createDate 2019/02/27
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void setPushProject(List<DeviceBusinessEntranceChangeLogPO> business) {
        try {
            List<PushCloudEntranceChangeLogPO> projects=new ArrayList<>();
            Set<String> pro = new HashSet<>();
            for (DeviceBusinessEntranceChangeLogPO bus : business) {
                if (pro.add(bus.getProjectId())) {
                    List<DeviceEntranceInfoPO> clouds = iCloudEntranceDao.getCloudEntranceByProjectId(business.get(0).getProjectId());
                    //查询项目信息
                    CloudElevatorPushProjectCommanDataVO cloudElevatorPushProjectCommanDataVO = iPushCloudElevatorChangeLogDao.getEntranceProjectById(business.get(0).getProjectId());
                    CloudEntrancePushProjectCommandDataVO vo =new CloudEntrancePushProjectCommandDataVO();
                    vo.setProjectName(cloudElevatorPushProjectCommanDataVO.getProjectName());
                    vo.setRootPort(cloudElevatorPushProjectCommanDataVO.getRootPort());
                    vo.setRootPwd(cloudElevatorPushProjectCommanDataVO.getRootPwd());
                    vo.setPropertyValueOpen(cloudElevatorPushProjectCommanDataVO.getPropertyValueOpen());
                    vo.setOperationMode(cloudElevatorPushProjectCommanDataVO.getChargeMode());
                    List<CloudIntercomDeviceVO.PropertyValue> list = iCloudIntercomDeviceServiceDao.getPropertyInfo(bus.getProjectId(),3);
                    if (list.size() == 0) {
                        list = new ArrayList<>();
                        list.add(new CloudIntercomDeviceVO.PropertyValue());
                    }
                    vo.setDeploys(list);

                    //处理云电梯和云群控器相关推送指令
                    List<CloudIntercomDeviceVO.PropertyValue> listElevator = iCloudIntercomDeviceServiceDao.getPropertyInfo(bus.getProjectId(),2);
                    if (listElevator.size() == 0) {
                        listElevator = new ArrayList<>();
                        listElevator.add(new CloudIntercomDeviceVO.PropertyValue());
                    }
                    for(CloudIntercomDeviceVO.PropertyValue pv: listElevator){
                        pv.setDay(pv.getDay() == null ? 0 : pv.getDay());
                        pv.setPointOut(pv.getPointOut() == null ? 0 : pv.getPointOut());
                    }
                    vo.setElevatorDeploys(listElevator);

//                    vo.setChargeMode(cloudElevatorPushProjectCommanDataVO.getChargeMode());
                    for (DeviceEntranceInfoPO cloud : clouds) {
                        // 设置门禁机号
                        vo.setDoorNum(StringHandlerUtil.getDeviceIdByDeviceUnique(cloud.getDeviceUnique()));
                        PushCloudEntranceChangeLogPO po = new PushCloudEntranceChangeLogPO();
                        po.setCommandType(PushCloudEntranceChangeEnum.PUSH_PROJECT.getType());
                        po.setCommandId(LogicIdUtil.bussinessId());
                        po.setCommandData(JsonUtil.toJSON(vo));
                        po.setDeviceUnique(cloud.getDeviceUnique());
                        po.setSn(cloud.getSn());
                        po.setStatus(DataStatusEnum.NORMAL.getType());
                        po.setCommandStatus(0);
                        po.setCreateTime(new Date());
                        po = (PushCloudEntranceChangeLogPO) StringHandlerUtil.formatString(po);
                        projects.add(po);
                    }
                    break;
                }
            }
            if (!projects.isEmpty()) {
                iPushCloudEntranceChangeLogDao.batchSave(projects);
                this.sendIotMessage(projects);
            }
        }catch (Exception e){
            throw new DataAccessException("【定时任务】同步云门禁业务指令至响应硬件结果表项目信息执行失败，当前时间】:" +
                    DateUtil.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss")+":"+e);
        }
    }

    /**
     * <desc>
     *      处理推送设备响应固定密码信息
     * </desc>
     *
     * @param business 业务数据
     * @author wangzhi
     * @createDate 2019/02/27
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void setPushFixedPassword(List<DeviceBusinessEntranceChangeLogPO> business) {
        try {
            List<PushCloudEntranceChangeLogPO> passwords = new ArrayList<>();
            Set<String> buildSet = new HashSet<>();
            Set<String> roomSet = new HashSet<>();
            for (DeviceBusinessEntranceChangeLogPO bus : business) {
                //LOG.info("云门禁固定密码信息指令处理命令数据：" + bus + "，指令id：" + bus.getId());
                List<Map<String,Object>> rms = JsonUtil.decode(bus.getCommandParameter(), new TypeReference<List<Map<String, Object>>>() {});
                //LOG.info("云门禁固定密码信息指令处理命令数据转换对象后：" + rms);
                for(Map<String,Object> map : rms){
                    String buildId = map.get("buildId").toString();
                    String roomId = map.get("roomId").toString();
                    buildSet.add(buildId);
                    roomSet.add(roomId);
                }
                LOG.info("云门禁固定密码信息指令处理命令数据buildSet：" + buildSet);
                if (buildSet.isEmpty()) {
                    continue;
                }
                List<CloudElevatorByBuildIdVO> cloudElevatorByBuildIdVOList = iCloudEntranceDao.getCloudEntranceByBuildId(buildSet);
                for(CloudElevatorByBuildIdVO vo : cloudElevatorByBuildIdVOList){
                    PushCloudEntranceChangeLogPO ownedPush = new PushCloudEntranceChangeLogPO();
                    ownedPush.setDeviceUnique(vo.getDeviceUnique());
                    ownedPush.setCommandId(LogicIdUtil.bussinessId());
                    ownedPush.setSn(vo.getSn());
                    ownedPush.setStatus(DataStatusEnum.NORMAL.getType());
                    ownedPush.setCommandStatus(0);
                    ownedPush.setCreateTime(new Date());
                    ownedPush.setCommandType(PushCloudEntranceChangeEnum.PUSH_ROOM_PWD.getType());
                    //根据roomId去查找room的信息，赋值于commandData
                    List<PushRoomCommandDataByCloudEntranceVO> voList = new ArrayList<>();
                    for(String roomId : roomSet){
                        if (StringUtils.isBlank(vo.getSn())) {
                            continue;
                        }
                        //查询设备下的房间id集合
                        String roomIdStr =  iCloudEntranceDao.getRoomInfoByEntrance(vo.getDeviceUnique());
                        if(roomIdStr == null || !roomIdStr.contains(roomId)){
                            continue;
                        }
                        Map<String, Object> roomInfoMap = iCloudEntranceDao.getRoomInfo(roomId,vo.getSn().substring(0,8));
                        if (roomInfoMap != null && !roomInfoMap.isEmpty()) {
                            PushRoomCommandDataByCloudEntranceVO pushRoomCommandDataByCloudEntranceVO = new PushRoomCommandDataByCloudEntranceVO();
                            pushRoomCommandDataByCloudEntranceVO.setDoorNum(StringHandlerUtil.getDeviceIdByDeviceUnique(vo.getDeviceUnique()));
                            pushRoomCommandDataByCloudEntranceVO.setOpenPwd(roomInfoMap.get("openPwd") == null ? "" : roomInfoMap.get("openPwd").toString());
                            pushRoomCommandDataByCloudEntranceVO.setRoomId(roomInfoMap.get("roomId") == null ? "" : roomInfoMap.get("roomId").toString());
                            pushRoomCommandDataByCloudEntranceVO.setRoomNum(roomInfoMap.get("roomNum").toString());
                            pushRoomCommandDataByCloudEntranceVO.setLiftDoorType(roomInfoMap.get("liftDoorType").toString());
                            pushRoomCommandDataByCloudEntranceVO.setStatus(roomInfoMap.get("status").toString());
                            pushRoomCommandDataByCloudEntranceVO.setSoftCardNums(roomInfoMap.get("softCardNums") == null ? "" : roomInfoMap.get("softCardNums").toString());
                            pushRoomCommandDataByCloudEntranceVO.setHardCardNums(StringHandlerUtil.getNullOrStringForObject(roomInfoMap.get("hardCardNums")));
                            pushRoomCommandDataByCloudEntranceVO.setFingerNums(StringHandlerUtil.getNullOrStringForObject(roomInfoMap.get("fingerNums")));
                            pushRoomCommandDataByCloudEntranceVO.setArrearsTime(roomInfoMap.get("arrearsTime") == null ? "" : roomInfoMap.get("arrearsTime").toString());
                            pushRoomCommandDataByCloudEntranceVO = (PushRoomCommandDataByCloudEntranceVO) StringHandlerUtil.formatString(pushRoomCommandDataByCloudEntranceVO);
                            voList.add(pushRoomCommandDataByCloudEntranceVO);
                        } else {
                            Map<String, Object> roomMap = iCloudEntranceDao.getRoomNumByRoomId(roomId);
                            RoomInfoPO roomInfo = iPushCloudElevatorChangeLogDao.getRoomInfoByRoomId(roomId);
                            PushRoomCommandDataByCloudEntranceVO pushRoomCommandDataByCloudEntranceVO = new PushRoomCommandDataByCloudEntranceVO();
                            pushRoomCommandDataByCloudEntranceVO.setDoorNum(StringHandlerUtil.getDeviceIdByDeviceUnique(vo.getDeviceUnique()));
                            pushRoomCommandDataByCloudEntranceVO.setOpenPwd("");
                            pushRoomCommandDataByCloudEntranceVO.setRoomId(roomId);
                            pushRoomCommandDataByCloudEntranceVO.setRoomNum(roomMap.get("roomNum").toString());
                            pushRoomCommandDataByCloudEntranceVO.setLiftDoorType(roomMap.get("liftDoorType").toString());
                            pushRoomCommandDataByCloudEntranceVO.setStatus(roomMap.get("status").toString());
                            pushRoomCommandDataByCloudEntranceVO.setSoftCardNums(roomInfo.getSoftCardNums());
                            pushRoomCommandDataByCloudEntranceVO.setHardCardNums(roomInfo.getHardCardNums());
                            pushRoomCommandDataByCloudEntranceVO.setFingerNums(roomInfo.getFingerNums());
                            pushRoomCommandDataByCloudEntranceVO.setArrearsTime(roomInfo.getArrearsTime());
                            pushRoomCommandDataByCloudEntranceVO = (PushRoomCommandDataByCloudEntranceVO) StringHandlerUtil.formatString(pushRoomCommandDataByCloudEntranceVO);
                            voList.add(pushRoomCommandDataByCloudEntranceVO);
                        }
                    }
                    if (voList.size() > 0) {
                        ownedPush.setCommandData(JsonUtil.toJSON(voList));
                        passwords.add(ownedPush);
                    }
                }
            }
            if (!passwords.isEmpty()) {
                iPushCloudEntranceChangeLogDao.batchSave(passwords);
                this.sendIotMessage(passwords);
            }
        } catch (Exception e) {
            e.printStackTrace();
            LOG.error("【定时任务】同步云门禁业务指令至响应硬件结果固定密码信息执行失败"+e.getMessage());
            throw new DataAccessException("【定时任务】同步云门禁业务指令至响应硬件结果固定密码信息执行失败，当前时间】:" +
                    DateUtil.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss")+"："+e);
        }
    }

    /**
     * <desc>
     *      处理推送硬件响应设备信息
     * </desc>
     *
     * @param business 业务数据
     * @author wangzhi
     * @createDate 2019/02/27
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void setPushDevice(List<DeviceBusinessEntranceChangeLogPO> business){
        try {
            List<PushCloudEntranceChangeLogPO> devices = new ArrayList<>();
            Map<String, Object> deviceMap = new HashMap<>();
            for (DeviceBusinessEntranceChangeLogPO bus : business) {
                List<Map<String, Object>> list =  JsonUtil.decode(bus.getCommandParameter(), new TypeReference<List<Map<String, Object>>>() {});
                Set<String> deviceUniques = new HashSet<>();
                list.forEach(deviceUnique -> {
                    deviceUniques.add(deviceUnique.get("deviceUnique").toString());
                });
                for (String deviceUnique : deviceUniques) {
                    Set<String> deviceSet = deviceMap.get(deviceUnique) == null ? new HashSet<>() : (Set<String>) deviceMap.get(deviceUnique);
                    if (deviceSet.add(deviceUnique)) {
                        deviceMap.put(deviceUnique, deviceSet);
                        //判断是否已有相同设备的推送消息
                        PushCloudEntranceChangeLogPO ownedPush = new PushCloudEntranceChangeLogPO();
                        ownedPush.setCommandType(PushCloudEntranceChangeEnum.PUSH_DEVICE.getType());
                        ownedPush.setCommandId(LogicIdUtil.bussinessId());
                        ownedPush.setStatus(DataStatusEnum.NORMAL.getType());
                        ownedPush.setCommandStatus(0);
                        ownedPush.setCreateTime(new Date());
                        //查询设备详情
                        DeviceEntranceInfoPO deviceInfo = iCloudEntranceDao.getDeviceInfoByDeviceUnique(deviceUnique);
                        ownedPush.setDeviceUnique(deviceUnique);
                        ownedPush.setSn(deviceInfo.getSn());
                        PushDeviceEntranceCommandDataVO vo = new PushDeviceEntranceCommandDataVO();
                        vo.setDeviceName(deviceInfo.getDeviceName());
                        if(deviceInfo.getStatus() == 1){
                            vo.setIsSmartCommunity("1");
                        }else{
                            vo.setIsSmartCommunity("0");
                        }
                        vo.setDoorNum(deviceInfo.getDeviceId());
                        vo.setEquipMode(deviceInfo.getEquipMode() + "");
                        vo = (PushDeviceEntranceCommandDataVO) StringHandlerUtil.formatString(vo);
                        ownedPush.setCommandData(JsonUtil.toJSON(vo));
                        devices.add(ownedPush);
                    }
                }
            }
            if (!devices.isEmpty()) {
                iPushCloudEntranceChangeLogDao.batchSave(devices);
                this.sendIotMessage(devices);
            }
        }catch (Exception e){
            throw new DataAccessException("【定时任务】同步云门禁业务指令至响应硬件结果表设备信息执行失败，当前时间】:" +
                    DateUtil.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss") + ":"+e);
        }
    }

    /**
     * <desc>
     *      处理推送设备项目信息变更
     * </desc>
     *
     * @param business 业务数据
     * @author wangzhi
     * @createDate 2019/04/29
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void setPushUserProject(List<DeviceBusinessEntranceChangeLogPO> business,Integer type){
        try {
            Map<String, Object> addressMap = new HashMap<>();
            List<PushCloudEntranceChangeLogPO> users = new ArrayList<>();
            for(DeviceBusinessEntranceChangeLogPO bus : business) {
                if (StringUtils.isNotBlank(bus.getCommandParameter()) && !bus.getCommandParameter().equals("[]")) {
                    //根据type 解析map的结构
                    Map<String, Object> map = new HashMap<>();
                    if (type == 1) {
                        Map<String, Object> projectMap = JsonUtil.toObject(bus.getCommandParameter(), HashMap.class);
                        map.put(projectMap.get("userId").toString(), projectMap.get("userId"));
                    } else {
                        List<Map<String, Object>> userRoom = JsonUtil.decode(bus.getCommandParameter(), new TypeReference<List<Map<String, Object>>>() {
                        });
                        userRoom.forEach(user->{
                            if (map.get(user.get("userId").toString()) == null) {
                                map.put(user.get("userId").toString(), user.get("userId").toString());
                            }
                        });
                        for (String userId : map.keySet()) {
                            Set<String> roomSet = new HashSet<>();
                            userRoom.forEach(ur -> {
                                if (ur.get("userId").toString().equals(userId)) {
                                    roomSet.add(ur.get("roomId").toString());
                                }
                            });
                            map.put(userId, roomSet.toArray(new String[roomSet.size()]));
                        }
                    }
                    for (String userId : map.keySet()) {
                        //获取项目下有权限的所有云门禁设备信息
                        List<AppCloudIntercomsVO> clouds = iCloudEntranceDao.getUserClouds(userId, bus.getProjectId());
                        if (clouds == null || clouds.isEmpty()) {
                            continue;
                        }
                        for (AppCloudIntercomsVO cloud : clouds) {
                            List<PushUserEntranceCommandDataVO> voList;
                            //判断是否已有相同设备的推送消息
                            PushCloudEntranceChangeLogPO ownedPush;
                            try {
                                ownedPush = users.stream().filter(roomUser -> roomUser.getDeviceUnique().equals(cloud.getDeviceUnique())).findFirst().get();
                            } catch (NoSuchElementException e) {
                                ownedPush = null;
                            }
                            //获取用户房间号
                            String[] roomIds;
                            if (type == 1) {
                                roomIds = StringHandlerUtil.splitString(cloud.getRoomIds());
                            } else {
                                roomIds = (String[]) map.get(userId);
                            }
                            //如果没有房间
                            if (roomIds.length < 1) {
                                continue;
                            }
                            if (ownedPush != null) {
                                voList = (List<PushUserEntranceCommandDataVO>) JsonUtil.toListObject(ownedPush.getCommandData(), ArrayList.class, PushUserEntranceCommandDataVO.class);
                            } else {
                                ownedPush = new PushCloudEntranceChangeLogPO();
                                ownedPush.setCommandId(LogicIdUtil.bussinessId());
                                ownedPush.setDeviceUnique(cloud.getDeviceUnique());
                                ownedPush.setCreateTime(new Date());
                                ownedPush.setCommandStatus(0);
                                ownedPush.setStatus(DataStatusEnum.NORMAL.getType());
                                ownedPush.setCommandType(PushCloudEntranceChangeEnum.PUSH_USER.getType());
                                //获取设备sn
                                ownedPush.setSn(iCloudEntranceDao.getSnByDeviceUnique(cloud.getDeviceUnique()));
                                voList = new ArrayList<>();
                                users.add(ownedPush);
                            }
                            if (roomIds.length > 0) {
                                for (String roomId : roomIds) {
                                    //判断在需要更新的设备中是否有相同的用户房间信息
                                    Optional<PushUserEntranceCommandDataVO> optUser = voList.stream().filter(pu -> pu.getUserId().equals(userId) && pu.getRoomId().equals(roomId)).findFirst();
                                    if (!optUser.isPresent()) {
                                        PushUserEntranceCommandDataVO pushUser = new PushUserEntranceCommandDataVO();
                                        pushUser.setDoorNum(StringHandlerUtil.getDeviceIdByDeviceUnique(cloud.getDeviceUnique()));
                                        pushUser.setUserId(userId);
                                        pushUser.setRoomId(roomId);
                                        if (iCloudEntranceDao.checkDeviceInRoom(cloud.getDeviceUnique(), roomId) > 0) {
                                            //查询用户的项目信息
                                            Map<String, Object> projectInfo;
                                            try {
                                                projectInfo = iCloudTalkPushCloudIntercomChangeLogDao.getPushUserProjectInfo(pushUser.getUserId(), bus.getProjectId(), pushUser.getRoomId());
                                                if (projectInfo == null) {
                                                    continue;
                                                }
                                            } catch (Exception e) {
                                                LOG.error(String.format("【同步云门禁业务指令至响应硬件结果表用户信息执行失败：用户与项目信息有多条】 用户Id:%s 项目id:%s", pushUser.getUserId(), bus.getProjectId()));
                                                continue;
                                            }

                                            pushUser.setUserName(projectInfo.get("userName") == null ? "" : projectInfo.get("userName").toString());
                                            pushUser.setIdcardKey(StringHandlerUtil.getNullOrStringForObject(projectInfo.get("idcardKey")));
                                            pushUser.setIsLoss(StringHandlerUtil.getNullOrStringForObject(projectInfo.get("isLoss")));
                                            pushUser.setStartTime(null);
                                            pushUser.setEndTime(null);
                                            //组装用户信息vip标识符
                                            if (projectInfo.get("userLabel")==null){
                                                    pushUser.setIsVip(0);
                                            }else {
                                                    pushUser.setIsVip(Arrays.asList(projectInfo.get("userLabel").toString().split(",")).contains("1")?1:0);
                                            }
                                            //组装常用楼层和公共楼层
                                            //1.得到用户所拥有的楼层机号对应关系
                                            String commonFloor = StringHandlerUtil.getNullOrStringForObject(projectInfo.get("commonFloor"));
                                            String publicFloor = StringHandlerUtil.getNullOrStringForObject(projectInfo.get("publicFloor"));


                                            //2获取当前设备的所在 地址
                                            List<Map> untilMap = iAppDeviceDao.getDeviceEntranceBridgeInfoByDeviceUnique(cloud.getDeviceUnique());
                                            //
                                            for (Map<String, Object>  untilmap : untilMap) {
                                                Map jsonCommonFloor=null;
                                                Map jsonPublicFloor=null;
                                                if (commonFloor!=null){
                                                    jsonCommonFloor = JSON.parseObject(commonFloor, HashMap.class);
                                                }
                                                if (publicFloor!=null){
                                                    jsonPublicFloor = JSON.parseObject(publicFloor, HashMap.class);
                                                }

                                                //3.获取当前地址的下的电梯 正背们和机号
                                                List<CloudElevatorVO> DeviceUniques = iPropertyEquipDao.getElevatorListByAddress(untilmap);
                                                for (CloudElevatorVO cloudElevatorVO : DeviceUniques)     {
                                                    Map<String, Object> elevator = iCloudTalkPushCloudIntercomChangeLogDao.getElevatorByDeviceUnique(cloudElevatorVO.getDeviceUnique());
                                                    if (commonFloor==null){
                                                        if ("1".equals((elevator==null?null:elevator.get("liftDoorType")+""))){
                                                            //正门常用楼层
                                                            pushUser.setFrontCommonFloor("");
                                                        }else {
                                                            pushUser.setBackCommonFloor("");
                                                        }
                                                    }else {
                                                        if (jsonCommonFloor.containsKey(cloudElevatorVO.getDeviceUnique())){
                                                            if ("1".equals((elevator==null?null:elevator.get("liftDoorType")+""))){
                                                                //正门常用楼层
                                                                pushUser.setFrontCommonFloor("x".equals(jsonCommonFloor.get(cloudElevatorVO.getDeviceUnique()).toString())?"":jsonCommonFloor.get(cloudElevatorVO.getDeviceUnique()).toString());
                                                            }else {
                                                                pushUser.setBackCommonFloor("x".equals(jsonCommonFloor.get(cloudElevatorVO.getDeviceUnique()).toString())?"":jsonCommonFloor.get(cloudElevatorVO.getDeviceUnique()).toString());
                                                            }
                                                        }
                                                    }
                                                    if (publicFloor==null){
                                                        if ("1".equals((elevator==null?null:elevator.get("liftDoorType")+""))){
                                                            //正门常用楼层
                                                            pushUser.setFrontPublicFloor("");
                                                        }else {
                                                            pushUser.setBackPublicFloor("");
                                                        }
                                                    }else {
                                                        if (jsonPublicFloor.containsKey(cloudElevatorVO.getDeviceUnique())){
                                                            if ("1".equals((elevator==null?null:elevator.get("liftDoorType")+""))){
                                                                //正门常用楼层
                                                                pushUser.setFrontPublicFloor("x".equals(jsonPublicFloor.get(cloudElevatorVO.getDeviceUnique()).toString())?"":jsonPublicFloor.get(cloudElevatorVO.getDeviceUnique()).toString());
                                                            }else {
                                                                pushUser.setBackPublicFloor("x".equals(jsonPublicFloor.get(cloudElevatorVO.getDeviceUnique()).toString())?"":jsonPublicFloor.get(cloudElevatorVO.getDeviceUnique()).toString());
                                                            }
                                                        }
                                                    }

                                                }
                                            }

                                            pushUser.setVisitorType(0);
                                            pushUser.setFacePicUrl(projectInfo.get("imageUrl") == null ? "" : projectInfo.get("imageUrl").toString());
                                            String userRoomStatus = projectInfo.get("userRoomStatus").toString();
                                            String userProjectStatus = projectInfo.get("userProjectStatus").toString();
                                            String projectStatus = projectInfo.get("projectStatus").toString();
                                            String status = projectInfo.get("status").toString();
                                            if (userRoomStatus.equals("2") && userProjectStatus.equals("1") && status.equals("1") && projectStatus.equals("1")) {
                                                pushUser.setStatus("1");
                                            } else {
                                                pushUser.setStatus("0");
                                            }
                                            pushUser = (PushUserEntranceCommandDataVO) StringHandlerUtil.formatString(pushUser);
                                            voList.add(pushUser);
                                        }
                                    }
                                }
                            }
                            if (voList.isEmpty()) {
                                continue;
                            }
                            ownedPush.setCommandData(JsonUtil.toJSON(voList));
                        }
                    }
                    for (String userId : map.keySet()) {
                        //访客的时候
                        //获取访客信息 以及 房间下的云电梯设备
                        List<PushCloudVisitorInfoDeviceVO> list = iCloudEntranceDao.getVisitorDeviceInfo(userId);
                        for (PushCloudVisitorInfoDeviceVO vo : list) {
                            List<PushUserEntranceCommandDataVO> voList = new ArrayList<>();
                            PushCloudEntranceChangeLogPO ownedPush = new PushCloudEntranceChangeLogPO();
                            ownedPush.setCommandId(LogicIdUtil.bussinessId());
                            ownedPush.setDeviceUnique(vo.getDeviceUnique());
                            ownedPush.setSn(vo.getSn());
                            ownedPush.setCreateTime(new Date());
                            ownedPush.setCommandStatus(0);
                            ownedPush.setStatus(DataStatusEnum.NORMAL.getType());
                            ownedPush.setCommandType(PushCloudEntranceChangeEnum.PUSH_USER.getType());
                            ownedPush.setSn(vo.getSn());

                            PushUserEntranceCommandDataVO pushUser = new PushUserEntranceCommandDataVO();
                            pushUser.setDoorNum(StringHandlerUtil.getDeviceIdByDeviceUnique(vo.getDeviceUnique()));
                            pushUser.setUserId(vo.getVFaceId() == null ? "" : vo.getVFaceId());
                            pushUser.setUserName(vo.getVisitorName() == null ? "" : vo.getVisitorName());
                            pushUser.setStartTime(vo.getStartTime());
                            pushUser.setEndTime(vo.getEndTime());
                            pushUser.setRoomId(vo.getRoomId());
                            pushUser.setIdcardKey(vo.getIdcardKey() == null ? "" : vo.getIdcardKey());
                            pushUser.setIsLoss("");
                            pushUser.setVisitorType(1);
                            pushUser.setStatus(vo.getStatus());
                            pushUser.setFacePicUrl(vo.getFacePicUrl() == null ? "" : vo.getFacePicUrl());
                            pushUser.setIsVip(0);

                            voList.add(pushUser);
                            ownedPush.setCommandData(JsonUtil.toJSON(voList));
                            users.add(ownedPush);
                        }
                    }
                }
            }
            for (int i=users.size()-1;i>=0;i--) {
                PushCloudEntranceChangeLogPO po = users.get(i);
                if (po.getCommandData() == null || "[]".equals(po.getCommandData())) {
                    users.remove(i);
                }
            }
            if (!users.isEmpty()) {
                iPushCloudEntranceChangeLogDao.batchSave(users);
                this.sendIotMessage(users);
            }
        } catch (Exception e) {
            LOG.error("【定时任务】同步云门禁业务指令至响应硬件结果用户项目信息执行失败" + e);
            e.printStackTrace();
        }
    }


    /**
     * <desc>
     *      处理门禁黑名单数据
     * </desc>
     *
     * @param business 业务数据
     * @author Jiaqi.X
     * @createDate 2019/10/15
     */
    public void setBlackList(List<DeviceBusinessEntranceChangeLogPO> business) throws IOException {
        List<PushCloudEntranceChangeLogPO> pushBlackList = new ArrayList<>();
        for (DeviceBusinessEntranceChangeLogPO bus : business) {
            Map<String, Object> roomMap = JsonUtil.toObject(bus.getCommandParameter(), HashMap.class);
            String roomId = roomMap.get("roomId").toString();
            String projectId = roomMap.get("projectId").toString();
            Map<String,Object> entrances = new HashMap<>();
            //获取房间下的门禁设备
            Map<String,Object> address = iPropertyEquipDao.getAddressByRoomId(roomId);
            List<CloudEntranceVO> entranceList = iPropertyEquipDao.getEntranceListByAddress(address);
            for(CloudEntranceVO entrance : entranceList){
                Set<String> userIds = new HashSet<>();
                String[] buildIds = StringHandlerUtil.splitString(entrance.getBuildIds());
                String[] unitIds = StringHandlerUtil.splitString(entrance.getUnitIds());
                EntranceBlackListVO entranceVO = new EntranceBlackListVO();
                entranceVO.setDoorNum(StringHandlerUtil.getDeviceIdByDeviceUnique(entrance.getMainDeviceUnique()));
                List<BlackListVO> blackList = new ArrayList<>();
                if(buildIds!=null || unitIds!=null) {
                    List<UserBlackInfoVO> users = iDeviceEntranceInfoDao.getUserBlackInfosByRoomId(roomId, entrance.getProjectId());
                    //地址用户
                    for (UserBlackInfoVO user : users) {
                        if(userIds.add(user.getUid()+user.getRoomNo())) {
                            BlackListVO blackListVO = new BlackListVO();
                            blackListVO.setUid(StringHandlerUtil.autlSupply(8, user.getUid(), "0"));
                            blackListVO.setType(1);
                            if ((user.getChargeMode()!=null && user.getChargeMode() == 1) && (user.getUsableCount() == null || user.getUsableCount() <= 0)) {
                                blackListVO.setStatus(1);
                            } else {
                                blackListVO.setStatus(0);
                            }
                            blackListVO.setBatch(Integer.valueOf(user.getBatch()));
                            blackListVO.setRoomNo(StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(user.getRoomNo())), "0").toUpperCase());
                            blackList.add(blackListVO);
                        }
                    }
                }
                //临时权限用户
                List<UserBlackInfoVO> tempUsers = iDeviceEntranceInfoDao.getTempBlackInfosByRoomId(roomId, entrance.getProjectId(),
                        Integer.valueOf(entrance.getMainDeviceUnique()));
                tempUsers.stream().forEach(user->{
                    if(userIds.add(user.getUid()+user.getRoomNo())) {
                        BlackListVO blackListVO = new BlackListVO();
                        blackListVO.setUid(StringHandlerUtil.autlSupply(8, user.getUid(), "0"));
                        blackListVO.setType(1);
                        if ((user.getChargeMode()!=null && user.getChargeMode() == 1) && (user.getUsableCount() == null || user.getUsableCount() <= 0)) {
                            blackListVO.setStatus(1);
                        }else{
                            blackListVO.setStatus(0);
                        }
                        blackListVO.setRoomNo(StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(user.getRoomNo())), "0").toUpperCase());
                        blackListVO.setBatch(Integer.valueOf(user.getBatch()));
                        blackList.add(blackListVO);
                    }
                });
                entranceVO.setBlackListArr(blackList);
                String group = iDeviceEntranceInfoDao.getEntranceGroup(entrance.getMainDeviceUnique());
                if(StringUtils.isNotBlank(group)) {
                    if(!blackList.isEmpty()) {
                        if (entrances.get(group) == null) {
                            List<EntranceBlackListVO> list = new ArrayList<>();
                            list.add(entranceVO);
                            entrances.put(group, list);
                        } else {
                            List<EntranceBlackListVO> list = (List<EntranceBlackListVO>) entrances.get(group);
                            list.add(entranceVO);
                            entrances.put(group, list);
                        }
                    }
                }
            }
            for(String group:entrances.keySet()){
                PushCloudEntranceChangeLogPO ownedPush = new PushCloudEntranceChangeLogPO();
                ownedPush.setCommandType(PushCloudEntranceChangeEnum.PUSH_BLACK.getType());
                ownedPush.setCommandId(LogicIdUtil.bussinessId());
                ownedPush.setStatus(DataStatusEnum.NORMAL.getType());
                ownedPush.setCommandStatus(0);
                ownedPush.setCreateTime(new Date());
                ownedPush.setDeviceUnique(projectId + "2" + StringHandlerUtil.getDeviceIdBySn(group));
                ownedPush.setSn(group);
                ownedPush.setCommandData(JsonUtil.toJSON(entrances.get(group)));
                ownedPush =  (PushCloudEntranceChangeLogPO)StringHandlerUtil.formatString(ownedPush);
                pushBlackList.add(ownedPush);
            }
        }
        if (!pushBlackList.isEmpty()) {
            iPushCloudEntranceChangeLogDao.batchSave(pushBlackList);
            this.sendIotMessage(pushBlackList);
        }
    }

    /**
     * <desc>
     *      处理推送硬件响应临时权限信息
     * </desc>
     *
     * @param business 业务数据
     * @author Jiaqi.X
     * @createDate 2019/02/27
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void setPushTempAuth(List<DeviceBusinessEntranceChangeLogPO> business) throws Exception {
        List<PushCloudEntranceChangeLogPO> devices = new ArrayList<>();
        for (DeviceBusinessEntranceChangeLogPO bus : business) {
            Map<String,Object> map = JsonUtil.toObject(bus.getCommandParameter(), HashMap.class);
            String oldDoorAuth = StringHandlerUtil.getNullOrStringForObject(map.get("doorAuth"));
            String[] oldDoorAuthDeviceIds = StringHandlerUtil.splitString(oldDoorAuth);
            List<String> oldDoorAuthList = Arrays.asList(oldDoorAuthDeviceIds);
            Map<String,Object> entrances = new HashMap<>();
            if(map.get("type").toString().equals("1")) {
                String userId =  map.get("userId").toString();
                String projectId = map.get("projectId").toString();
                List<Map<String, Object>> auths = iDeviceEntranceInfoDao.getPushTempAuths(projectId, userId);
                int delete = 0;
                List<String> addressDeviceIds = new ArrayList<>();
                if(auths.isEmpty()){
                    if(map.get("doorAuthList")!=null) {
                        delete = 1;
                        List<Map<String,Object>> doorAuthList = JsonUtil.decode(map.get("doorAuthList").toString(), new TypeReference<List<Map<String, Object>>>() {});
                        if(!doorAuthList.isEmpty()) {
                            auths.add(JsonUtil.decode(map.get("doorAuthList").toString(), new TypeReference<List<Map<String, Object>>>() {
                            }).get(0));
                        }
                    }
                }else{
                    //清除迁出地址下的设备
                    if(map.get("doorAuthList")!=null) {
                        AppEntranceOrCloudIntercomAuthVO doorVO = StringHandlerUtil.converEntranceOrCloudIntercomAuth(PropertyEquipTypeEnum.ENTRANCE.getType(),
                                JsonUtil.decode(map.get("doorAuthList").toString(), new TypeReference<List<Map<String, Object>>>() {
                                }));
                        if(doorVO!=null){
                            addressDeviceIds = doorVO.getDeviceIds();
                        }
                    }
                }
                for (Map<String, Object> auth : auths) {
                    //获取用户有权限的门禁设备机号
                    List<Map<String, Object>> doorAuth = iAppDeviceDao.getDoorAuth(map.get("userId").toString(), map.get("projectId").toString());
                    AppEntranceOrCloudIntercomAuthVO doorVO;
                    if(delete == 0) {
                        doorVO = StringHandlerUtil.converEntranceOrCloudIntercomAuth(PropertyEquipTypeEnum.ENTRANCE.getType(), doorAuth);
                    }else{
                        doorVO = StringHandlerUtil.converEntranceOrCloudIntercomAuth(PropertyEquipTypeEnum.ENTRANCE.getType(),
                                JsonUtil.decode(map.get("doorAuthList").toString(), new TypeReference<List<Map<String, Object>>>() {}));
                    }
                    for (String deviceId : doorVO.getDeviceIds()) {
                        EntranceTempAuthVO tempVO = new EntranceTempAuthVO();
                        tempVO.setDoorNum(deviceId);
                        tempVO.setUserId(StringHandlerUtil.getNullOrStringForObject(auth.get("userId")));
                        tempVO.setUserName(StringHandlerUtil.getNullOrStringForObject(auth.get("userName")));
                        tempVO.setIdcardKey(StringHandlerUtil.getNullOrStringForObject(auth.get("idcardKey")));
                        tempVO.setFacePicUrl(StringHandlerUtil.getNullOrStringForObject(auth.get("facePicUrl")));
                        tempVO.setVisitorType(auth.get("visitorType") != null ? Integer.valueOf(auth.get("visitorType").toString()) : null);
                        tempVO.setIsLoss(StringHandlerUtil.getNullOrStringForObject(auth.get("isLoss")));
                        String entranceType = iDeviceEntranceInfoDao.getEntranceType(map.get("projectId").toString() + "2" + deviceId);
                        if (delete == 0 && StringUtils.isNotBlank(entranceType) && entranceType .equals("23")) {
                            //查询门禁地址
                            Map<String, Object> address = iCloudEntranceDao.getDeviceAddress(map.get("projectId").toString() + "2" + deviceId);
                            if (address.get("buildId") == null && address.get("unitId") == null) {
                                continue;
                            }
                            //获取门禁地址下的电梯
                            List<CloudElevatorVO> elevators = iCloudElevatorDao.getDeviceUniquesByEntranceAddress(address);
                            //获取地址下电梯的临时权限
                            Set<String> frontFloor = new HashSet<>();           //正门楼层
                            Set<String> backFloor = new HashSet<>();            //背门楼层
                            for (CloudElevatorVO elevator : elevators) {
                                //获取电梯的授权设备信息
                                List<AppElevatorAuthDTO> elevatorAuths = iCloudElevatorDao.getFloorAuth(auth.get("userId").toString(),
                                        map.get("projectId").toString(), Integer.valueOf(elevator.getDeviceId()));
                                AppElevatorAuthVO tempElevatorAuth = StringHandlerUtil.convertElevatorAuth(elevatorAuths);
                                Optional<AppElevatorInfoVO> eAuth = tempElevatorAuth.getElevatorAuth().stream().filter(temp -> temp.getDeviceId().equals(elevator.getDeviceId())).findFirst();
                                if (eAuth.isPresent()) {
                                    String[] floors = StringHandlerUtil.splitString(eAuth.get().getLiveFloor());
                                    if(floors.length > 0){
                                        String floorsStr = iCloudElevatorDao.getFloorNumByNaturalFloor(floors,map.get("projectId").toString() + "1" + eAuth.get().getDeviceId());
                                        floors = StringHandlerUtil.splitString(floorsStr);
                                    }
                                    for (String floor : floors) {
                                        if (elevator.getLiftDoorType() == 1) {
                                            frontFloor.add(floor);
                                        } else {
                                            backFloor.add(floor);
                                        }
                                    }
                                }
                            }
                            tempVO.setFrontFloor(String.join(",", frontFloor));
                            tempVO.setBackFloor(String.join(",", backFloor));
                        }
                        if(delete == 0){
                            tempVO.setStatus(StringHandlerUtil.getNullOrStringForObject(auth.get("status")));
                        }else {
                            tempVO.setStatus("0");
                        }
                        tempVO = (EntranceTempAuthVO)StringHandlerUtil.formatString(tempVO);
                        String group = iDeviceEntranceInfoDao.getEntranceGroup(map.get("projectId").toString() + "2" + deviceId);
                        if(StringUtils.isNotBlank(group)) {
                            if (entrances.get(group) == null) {
                                List<EntranceTempAuthVO> list = new ArrayList<>();
                                list.add(tempVO);
                                entrances.put(group, list);
                            } else {
                                List<EntranceTempAuthVO> list = (List<EntranceTempAuthVO>) entrances.get(group);
                                list.add(tempVO);
                                entrances.put(group, list);
                            }
                        }
                    }
                    //迁出的地址权限
                    if(!addressDeviceIds.isEmpty()){
                        for(String deviceId:addressDeviceIds){
                            if(!doorVO.getDeviceIds().stream().filter(d->d.equals(deviceId)).findFirst().isPresent()){
                                EntranceTempAuthVO tempVO = new EntranceTempAuthVO();
                                tempVO.setDoorNum(deviceId);
                                tempVO.setUserId(StringHandlerUtil.getNullOrStringForObject(auth.get("userId")));
                                tempVO.setUserName(StringHandlerUtil.getNullOrStringForObject(auth.get("userName")));
                                tempVO.setIdcardKey(StringHandlerUtil.getNullOrStringForObject(auth.get("idcardKey")));
                                tempVO.setVisitorType(auth.get("visitorType") != null ? Integer.valueOf(auth.get("visitorType").toString()) : null);
                                tempVO.setIsLoss(StringHandlerUtil.getNullOrStringForObject(auth.get("isLoss")));
                                tempVO.setStatus("0");
                                tempVO = (EntranceTempAuthVO)StringHandlerUtil.formatString(tempVO);
                                String group = iDeviceEntranceInfoDao.getEntranceGroup(map.get("projectId").toString() + "2" + deviceId);
                                if(StringUtils.isNotBlank(group)) {
                                    if (entrances.get(group) == null) {
                                        List<EntranceTempAuthVO> list = new ArrayList<>();
                                        list.add(tempVO);
                                        entrances.put(group, list);
                                    } else {
                                        List<EntranceTempAuthVO> list = (List<EntranceTempAuthVO>) entrances.get(group);
                                        list.add(tempVO);
                                        entrances.put(group, list);
                                    }
                                }
                            }
                        }
                    }
                    //取消的临时权限
                    if(!oldDoorAuthList.isEmpty()){
                        for(String deviceId : oldDoorAuthList){
                            if(!doorVO.getDeviceIds().stream().filter(d->d.equals(deviceId)).findFirst().isPresent()){
                                EntranceTempAuthVO tempVO = new EntranceTempAuthVO();
                                tempVO.setDoorNum(deviceId);
                                tempVO.setUserId(StringHandlerUtil.getNullOrStringForObject(auth.get("userId")));
                                tempVO.setUserName(StringHandlerUtil.getNullOrStringForObject(auth.get("userName")));
                                tempVO.setIdcardKey(StringHandlerUtil.getNullOrStringForObject(auth.get("idcardKey")));
                                tempVO.setFacePicUrl(StringHandlerUtil.getNullOrStringForObject(auth.get("facePicUrl")));
                                tempVO.setVisitorType(auth.get("visitorType") != null ? Integer.valueOf(auth.get("visitorType").toString()) : null);
                                tempVO.setIsLoss(StringHandlerUtil.getNullOrStringForObject(auth.get("isLoss")));
                                tempVO.setStatus("0");
                                tempVO = (EntranceTempAuthVO)StringHandlerUtil.formatString(tempVO);
                                String group = iDeviceEntranceInfoDao.getEntranceGroup(map.get("projectId").toString() + "2" + deviceId);
                                if(StringUtils.isNotBlank(group)) {
                                    if (entrances.get(group) == null) {
                                        List<EntranceTempAuthVO> list = new ArrayList<>();
                                        list.add(tempVO);
                                        entrances.put(group, list);
                                    } else {
                                        List<EntranceTempAuthVO> list = (List<EntranceTempAuthVO>) entrances.get(group);
                                        list.add(tempVO);
                                        entrances.put(group, list);
                                    }
                                }
                            }
                        }
                    }
                }
                //如果取消的为最后的临时授权权限
                if(auths.isEmpty()&&!oldDoorAuthList.isEmpty()){
                    for(String deviceId : oldDoorAuthList){
                        Map<String,Object> userInfo = iCloudElevatorDao.getPushTempUserInfo(map.get("projectId").toString(),map.get("userId").toString());
                        EntranceTempAuthVO tempVO = new EntranceTempAuthVO();
                        tempVO.setDoorNum(deviceId);
                        tempVO.setUserId(StringHandlerUtil.getNullOrStringForObject(userInfo.get("userId")));
                        tempVO.setUserName(StringHandlerUtil.getNullOrStringForObject(userInfo.get("userName")));
                        tempVO.setIdcardKey(StringHandlerUtil.getNullOrStringForObject(userInfo.get("idcardKey")));
                        tempVO.setFacePicUrl(StringHandlerUtil.getNullOrStringForObject(userInfo.get("facePicUrl")));
                        tempVO.setVisitorType(userInfo.get("visitorType") != null ? Integer.valueOf(userInfo.get("visitorType").toString()) : null);
                        tempVO.setIsLoss(StringHandlerUtil.getNullOrStringForObject(userInfo.get("isLoss")));
                        tempVO.setStatus("0");
                        tempVO = (EntranceTempAuthVO)StringHandlerUtil.formatString(tempVO);
                        String group = iDeviceEntranceInfoDao.getEntranceGroup(map.get("projectId").toString() + "2" + deviceId);
                        if(StringUtils.isNotBlank(group)) {
                            if (entrances.get(group) == null) {
                                List<EntranceTempAuthVO> list = new ArrayList<>();
                                list.add(tempVO);
                                entrances.put(group, list);
                            } else {
                                List<EntranceTempAuthVO> list = (List<EntranceTempAuthVO>) entrances.get(group);
                                list.add(tempVO);
                                entrances.put(group, list);
                            }
                        }
                    }
                }
                for(String group:entrances.keySet()){
                    PushCloudEntranceChangeLogPO ownedPush = new PushCloudEntranceChangeLogPO();
                    ownedPush.setCommandType(PushCloudEntranceChangeEnum.PUSH_TEMP.getType());
                    ownedPush.setCommandId(LogicIdUtil.bussinessId());
                    ownedPush.setStatus(DataStatusEnum.NORMAL.getType());
                    ownedPush.setCommandStatus(0);
                    ownedPush.setCreateTime(new Date());
                    ownedPush.setDeviceUnique(map.get("projectId").toString() + "2" + StringHandlerUtil.getDeviceIdBySn(group));
                    ownedPush.setSn(group);
                    ownedPush.setCommandData(JsonUtil.toJSON(entrances.get(group)));
                    ownedPush =  (PushCloudEntranceChangeLogPO)StringHandlerUtil.formatString(ownedPush);
                    devices.add(ownedPush);
                }
            }else{
                //获取访客
                DeviceTempVisitorVO visitor = iDeviceEntranceInfoDao.getVisitorsByVisitorId(map.get("userId").toString());
                Set<String> deviceUniques = new HashSet<>();
                if(StringUtils.isNotBlank(visitor.getOwnerAuthDeviceUnique())){
                    for(String deviceUnique:StringHandlerUtil.splitString(visitor.getOwnerAuthDeviceUnique())){
                        if(deviceUnique.substring(8,9).equals("2")){
                            deviceUniques.add(deviceUnique);
                        }
                    }
                }
                for(String deviceUnique : deviceUniques) {
                    EntranceTempAuthVO tempVO = new EntranceTempAuthVO();
                    BeanUtils.copyProperties(visitor, tempVO);
                    List<CloudEntranceVO> entranceList = iDeviceEntranceInfoDao.getEntranceInfos(StringHandlerUtil.splitString(deviceUnique));
                    if(entranceList == null || entranceList.isEmpty()){
                        continue;
                    }
                    tempVO.setDoorNum(StringHandlerUtil.getDeviceIdByDeviceUnique(deviceUnique));
                    if(entranceList.get(0).getEntranceCategory().equals(23)) {
                        //查询门禁地址
                        Map<String, Object> address = iCloudEntranceDao.getDeviceAddress(deviceUnique);
                        if (address != null) {
                            //获取门禁地址下的电梯
                            List<CloudElevatorVO> elevators = iCloudElevatorDao.getDeviceUniquesByEntranceAddress(address);
                            if (StringUtils.isNotBlank(visitor.getFrontElevatorAuth())) {
                                Map<String, Object> frontList = JsonUtil.toObject(visitor.getFrontElevatorAuth(), HashMap.class);
                                Set<String> fronts = new HashSet<>();
                                for (String key : frontList.keySet()) {
                                    Optional<CloudElevatorVO> optional = elevators.stream().filter(elevator -> elevator.getDeviceId().equals(key)).findFirst();
                                    if (optional.isPresent()) {
                                        String[] floor = StringHandlerUtil.splitString(frontList.get(key).toString());
                                        if (floor.length > 0) {
                                            String floors = iCloudElevatorDao.getFloorNumByNaturalFloor(floor, optional.get().getProjectId() + "1" + optional.get().getDeviceId());
                                            floor = StringHandlerUtil.splitString(floors);
                                        }
                                        for (String f : floor) {
                                            fronts.add(f);
                                        }
                                    }
                                }
                                tempVO.setFrontFloor(String.join(",", fronts));
                            }
                            if (StringUtils.isNotBlank(visitor.getBackElevatorAuth())) {
                                Map<String, Object> backList = JsonUtil.toObject(visitor.getBackElevatorAuth(), HashMap.class);
                                Set<String> backs = new HashSet<>();
                                for (String key : backList.keySet()) {
                                    Optional<CloudElevatorVO> optional = elevators.stream().filter(elevator -> elevator.getDeviceId().equals(key)).findFirst();
                                    if (optional.isPresent()) {
                                        String[] floor = StringHandlerUtil.splitString(backList.get(key).toString());
                                        if (floor.length > 0) {
                                            String floors = iCloudElevatorDao.getFloorNumByNaturalFloor(floor, optional.get().getProjectId() + "1" + optional.get().getDeviceId());
                                            floor = StringHandlerUtil.splitString(floors);
                                        }
                                        for (String f : floor) {
                                            backs.add(f);
                                        }
                                    }
                                }
                                tempVO.setBackFloor(String.join(",", backs));
                            }
                        }
                    }
                    tempVO = (EntranceTempAuthVO)StringHandlerUtil.formatString(tempVO);
                    String group = iDeviceEntranceInfoDao.getEntranceGroup(deviceUnique);
                    if(StringUtils.isNotBlank(group)) {
                        if (entrances.get(group) == null) {
                            List<EntranceTempAuthVO> list = new ArrayList<>();
                            list.add(tempVO);
                            entrances.put(group, list);
                        } else {
                            List<EntranceTempAuthVO> list = (List<EntranceTempAuthVO>) entrances.get(group);
                            list.add(tempVO);
                            entrances.put(group, list);
                        }
                    }
                }
                for(String group:entrances.keySet()){
                    PushCloudEntranceChangeLogPO ownedPush = new PushCloudEntranceChangeLogPO();
                    ownedPush.setCommandType(PushCloudEntranceChangeEnum.PUSH_TEMP.getType());
                    ownedPush.setCommandId(LogicIdUtil.bussinessId());
                    ownedPush.setStatus(DataStatusEnum.NORMAL.getType());
                    ownedPush.setCommandStatus(0);
                    ownedPush.setCreateTime(new Date());
                    ownedPush.setDeviceUnique(map.get("projectId").toString() + "2" + StringHandlerUtil.getDeviceIdBySn(group));
                    ownedPush.setSn(group);
                    ownedPush.setCommandData(JsonUtil.toJSON(entrances.get(group)));
                    ownedPush =  (PushCloudEntranceChangeLogPO)StringHandlerUtil.formatString(ownedPush);
                    devices.add(ownedPush);
                }
            }
        }
        if (!devices.isEmpty()) {
            iPushCloudEntranceChangeLogDao.batchSave(devices);
            this.sendIotMessage(devices);
        }
    }

    /**
     * <desc>
     *      处理推送设备响应多媒体信息
     * </desc>
     *
     * @author Jiaqi.X
     * @createDate 2017/12/07
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void setPushMedia(List<DeviceBusinessEntranceChangeLogPO> business){
        try {
            List<PushCloudEntranceChangeLogPO> medias = new ArrayList<>();
            Set<String> pro = new HashSet<>();              //已经执行过的项目
            for (DeviceBusinessEntranceChangeLogPO bus : business) {
                if (pro.add(bus.getProjectId())) {
                    if (StringUtils.isNotBlank(bus.getCommandParameter())) {
                        //查询项目下所有的云对讲设备
                        // 获取所有云门禁设备
                        List<DeviceEntranceInfoPO> clouds = iCloudEntranceDao.getCloudUnibodyEntranceByProjectId(bus.getProjectId());
                        for (DeviceEntranceInfoPO cloud : clouds) {
                            PushCloudEntranceChangeLogPO push = new PushCloudEntranceChangeLogPO();
                            push.setCommandType(PushCloudEntranceChangeEnum.PUSH_MEDIA.getType());
                            push.setStatus(DataStatusEnum.NORMAL.getType());
                            push.setCreateTime(new Date());
                            push.setCommandId(LogicIdUtil.bussinessId());
                            push.setDeviceUnique(cloud.getDeviceUnique());
                            push.setSn(cloud.getSn());
                            push.setCommandStatus(0);
                            //图片类型多媒体信息
                            List<Map<String, Object>> pics = iPushCloudEntranceChangeLogDao.getMediasEntrance(push.getDeviceUnique(), MediaTypeEnum.IMGAE.getType().toString());
                            List<PushMediaCommanDataVO> picData = new ArrayList<>();
                            pics.forEach(pic -> {
                                picData.add(this.getMedias(pic, MediaTypeEnum.IMGAE));
                            });
                            push.setCommandData(JsonUtil.toJSON(picData));
                            medias.add(push);
                        }
                    }
                }
            }
            if (!medias.isEmpty()) {
                iPushCloudEntranceChangeLogDao.batchSave(medias);
                this.sendIotMessage(medias);
            }
        } catch (Exception e) {
            throw new DataAccessException("【定时任务】同步业务指令至响应硬件结果表多媒体信息执行失败，当前时间】:" +
                    DateUtil.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss") + "："+e);
        }
    }

    /**
     * <desc>
     *      封装多媒体数据实体
     * </desc>
     *
     * @param data 推送多媒体信息
     * @param typeEnum 多媒体类型枚举类
     * @return
     * @author Jiaqi.X
     * @createDate 2017/12/07
     */
    private  PushMediaCommanDataVO getMedias(Map<String,Object> data,MediaTypeEnum typeEnum){
        PushMediaCommanDataVO vo=new PushMediaCommanDataVO();
        vo.setType(StringHandlerUtil.getNullOrStringForObject(typeEnum.getType()));
        vo.setTitle(StringHandlerUtil.getNullOrStringForObject(data.get("title")));
        vo.setContent(StringHandlerUtil.getNullOrStringForObject(data.get("content")));
        vo.setAttacheFile(StringHandlerUtil.getNullOrStringForObject(data.get("attacheFile")));
        vo.setAttacheFileUrl(StringHandlerUtil.getNullOrStringForObject(data.get("attacheFileUrl")));
        vo.setMd5(StringHandlerUtil.getNullOrStringForObject(data.get("attacheFileMd5")));
        return (PushMediaCommanDataVO)StringHandlerUtil.formatString(vo);
    }

    /**
     * <desc>
     *      处理推送人脸库变更信息
     * </desc>
     *
     * @author Qiang.S
     * @createDate 2018/05/25
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void setPushFaceInfo(List<DeviceBusinessEntranceChangeLogPO> business) {
        try {
            List<PushCloudEntranceChangeLogPO> projects=new ArrayList<>();
            for (DeviceBusinessEntranceChangeLogPO bus : business) {
                // 获取所有云门禁设备
                List<DeviceEntranceInfoPO> clouds = iCloudEntranceDao.getCloudUnibodyEntranceByProjectId(bus.getProjectId());
                PushFaceInfoCommanDataVO vo = iCloudTalkPushCloudIntercomChangeLogDao.getFaceInfoById(business.get(0).getProjectId());
                //处理推送信息
                if (vo == null) {
                    vo = new PushFaceInfoCommanDataVO();
                    vo.setLivenessControl("");
                    vo.setQualityControl("");
                    vo.setGroupId("");
                    vo.setApiKey("");
                    vo.setAppId("");
                    vo.setSecretKey("");
                    vo.setScore(0);
                }else {
                    vo.setEnable(true);
                    if ("0".equals(vo.getLivenessControl())) {vo.setLivenessControl("LOW");}
                    if ("1".equals(vo.getLivenessControl())) {vo.setLivenessControl("NORMAL");}
                    if ("2".equals(vo.getLivenessControl())) {vo.setLivenessControl("HIGH");}
                    if ("3".equals(vo.getLivenessControl())) {vo.setLivenessControl("NONE");}
                }
                for (DeviceEntranceInfoPO cloud : clouds) {
                    //查询项目信息
                    PushCloudEntranceChangeLogPO po = new PushCloudEntranceChangeLogPO();
                    po.setCommandType(PushCloudEntranceChangeEnum.PUSH_FACE.getType());
                    po.setCommandId(LogicIdUtil.bussinessId());
                    JSONObject json = new JSONObject();
                    json.put("face",vo);
                    po.setCommandData(json.toString());
                    po.setDeviceUnique(cloud.getDeviceUnique());
                    po.setSn(cloud.getSn());
                    po.setCommandStatus(0);
                    po.setStatus(DataStatusEnum.NORMAL.getType());
                    po.setCreateTime(new Date());
                    po=(PushCloudEntranceChangeLogPO)StringHandlerUtil.formatString(po);
                    projects.add(po);
                }
            }
            if (!projects.isEmpty()) {
                iPushCloudEntranceChangeLogDao.batchSave(projects);
                this.sendIotMessage(projects);
            }
        }catch (Exception e){
            throw new DataAccessException("【定时任务】同步人脸库信息指令至响应硬件执行失败，当前时间】:" +
                    DateUtil.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss")+":"+e);
        }
    }

    /**
     * <desc>
     *      处理推送设备指令转换为iot指令
     * </desc>
     *
     * @param list 指令内容
     * @author Qiang.S
     * @createDate 2019/07/05
     */
    private void sendIotMessage (List<PushCloudEntranceChangeLogPO> list) {
        try {
            //过滤离线设备
            for (int i = list.size() - 1; i >= 0; i--) {
                if (StringUtils.isBlank(redisService.get(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY + list.get(i).getDeviceUnique())) &&
                        StringUtils.isBlank(redisService.get(RedisConstant.DEVICE_WIPPEN_IS_ONLINE_KEY + list.get(i).getDeviceUnique()))&&
                        StringUtils.isBlank(redisService.get(RedisConstant.DEVICE_UNIBODY_FACE_IS_ONLINE_KEY + list.get(i).getDeviceUnique()))) {
                    list.remove(i);
                }
            }
            if (list.size() > 0) {
                //取得所有在线门禁的主门禁设备编号,发送iot消息时使用
                List<DeviceEntranceInfoPO> entranceInfoPOS = iPushCloudEntranceChangeLogDao.getMainDeviceUnique(list);
                for (PushCloudEntranceChangeLogPO pushCloudEntranceChangeLogPO : list) {
                    for (DeviceEntranceInfoPO deviceEntranceInfoPO : entranceInfoPOS) {
                        if (pushCloudEntranceChangeLogPO.getDeviceUnique().equals(deviceEntranceInfoPO.getDeviceUnique())) {
                            pushCloudEntranceChangeLogPO.setMainDeviceUnique(deviceEntranceInfoPO.getBindDeviceGroup());
                            break;
                        }
                    }
                }
                //取得版本和iotkey
                ProductTypePO productKey = iPushCloudEntranceChangeLogDao.getEntranceVersonIotkey(list.get(0).getDeviceUnique());
                //iot指令准备
                for (PushCloudEntranceChangeLogPO po : list) {
                    //只发主设备
                    SendPushMessageTaskPO sendPushMessageTaskPO = new SendPushMessageTaskPO(productKey.getIotProductKey(),
                            "/" + po.getMainDeviceUnique() + (productKey.getIotVersion() == 1 ? "/user" : "") + IotCloudCtrlInstructEnum.DEVICECMD.getUrl(), po.getMainDeviceUnique(), "itlong", "2001", 0, po.getCommandType().toString(), 1,po.getIotFlag());
                    sendIotPushMessageQueue.getSendIotPushQueue().put(sendPushMessageTaskPO);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
